package com.example.wo.applicationwuziqi;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class Wuziqi extends View {
    private  int mPanelWidth;
    private float mLineHeight;
    private int MAX_LINE=10;
    private Paint paint = new Paint();
    private Bitmap mWhitePiece, mBlackPiece;
    private float ratioOfLineHeight =3*1.0f/4;
    private List<Point> mWhiteArray = new ArrayList<>();
    private List<Point> mBlackArray = new ArrayList<>();
    private Boolean isWhilte =true;
    private Boolean isGameOver = false;
    private Boolean isWhiteWiner;
    private int MAX_SUCCESS_LINE=5;
    public Wuziqi(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint.setColor(0x88000000);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);
        paint.setDither(true);
        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);
        mBlackPiece =BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width=MeasureSpec.getSize(widthMeasureSpec);
        int widthMode =MeasureSpec.getMode(widthMeasureSpec);
        int height =MeasureSpec.getSize(heightMeasureSpec);
        int heigehtMode =MeasureSpec.getMode(heightMeasureSpec);
        int result = Math.min(width,height);
        setMeasuredDimension(result,result);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mPanelWidth =w;
        mLineHeight= mPanelWidth*1.0f/MAX_LINE;
        int pieceWidth = (int) (mLineHeight*ratioOfLineHeight);
        mWhitePiece=Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);
        mBlackPiece=Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBoard(canvas);
        drawPieces(canvas);
        checkGameOver();
    }

    private void checkGameOver() {
       boolean whileWin = checkFiveInLine(mWhiteArray);
        boolean blackWin = checkFiveInLine(mBlackArray);
        if(whileWin||blackWin){
            isGameOver = true;
            isWhiteWiner =whileWin;
            String result = isWhiteWiner?"白棋胜利":"黑棋胜利";
            Toast.makeText(getContext(),result,Toast.LENGTH_SHORT).show();
        }
    }

    private boolean checkFiveInLine(List<Point> points) {
        for(Point point:points){
            int x=point.x;
            int y=point.y;
           boolean win= checkHorizonrtal( x , y ,points);
           if(win)return true;
            win= checkVetical( x , y ,points);
            if(win)return true;
            win= checkLeftDiagonal( x , y ,points);
            if(win)return true;
            win= checkRightDiagonal( x , y ,points);
            if(win)return true;



        }

        return  false;
    }

    private boolean checkHorizonrtal(int x, int y, List<Point> points) {
        int count=1;
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x-i,y))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x+i,y))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        return false;
    }
    private boolean checkVetical(int x, int y, List<Point> points) {
        int count=1;
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x,y-i))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x,y+i))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        return false;
    }
    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {
        int count=1;
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x-i,y+i))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x+i,y-i))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        return false;
    }
    private boolean checkRightDiagonal(int x, int y, List<Point> points) {
        int count=1;
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x-i,y-i))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        for(int i=1;i<MAX_SUCCESS_LINE;i++){
            if(points.contains(new Point(x+i,y+i))){
                count++;
            }else {
                break;
            }
        }
        if(count==MAX_SUCCESS_LINE){
            return true;
        }
        return false;
    }

    private void drawPieces(Canvas canvas) {
        for(int i=0;i<mWhiteArray.size();i++){
            Point whitePoint = mWhiteArray.get(i);
            canvas.drawBitmap(mWhitePiece,(whitePoint.x+(1-ratioOfLineHeight)/2)*mLineHeight,
                    (whitePoint.y+(1-ratioOfLineHeight)/2)*mLineHeight,null);
        }
        for(int i=0;i<mBlackArray.size();i++){
            Point blackPoint = mBlackArray.get(i);
            canvas.drawBitmap(mBlackPiece,(blackPoint.x+(1-ratioOfLineHeight)/2)*mLineHeight,
                    (blackPoint.y+(1-ratioOfLineHeight)/2)*mLineHeight,
                     null);
        }
    }

    private void drawBoard(Canvas canvas) {
        int w = mPanelWidth;
        float lineHeight = mLineHeight;
        for(int i=0;i<MAX_LINE;i++){
            int StartX = (int) (lineHeight/2);
            int EndX = (int) (w-lineHeight/2);
            int y = (int) ((0.5+i)*lineHeight);
            canvas.drawLine(StartX,y,EndX,y,paint);
            canvas.drawLine(y,StartX,y,EndX,paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(isGameOver==true)return  false;
        int action = event.getAction();
        if(action==MotionEvent.ACTION_UP){
            int x= (int) event.getX();
            int y = (int) event.getY();
            Point point = getVaidPoint(x,y);
            if(mWhiteArray.contains(point)||mBlackArray.contains(point)){
                return  false;
            }
            if(isWhilte){
                mWhiteArray.add(point);
            }else {
                mBlackArray.add(point);
            }
            invalidate();
            isWhilte=!isWhilte;
        }
        return true;


    }

    private Point getVaidPoint(int x, int y) {
        return new Point((int)(x/mLineHeight),(int)(y/mLineHeight));
    }
}
